package com.westar.core.services;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.westar.base.businessUtil.EditAffairUtil;
import com.westar.base.businessUtil.NextTaskInfoUtil;
import com.westar.base.businessUtil.ViewTaskUtil;
import com.westar.base.cons.Constant;
import com.westar.base.exceptions.AffariBusinessException;
import com.westar.base.exceptions.LoginException;
import com.westar.base.exceptions.SelfHttpException;
import com.westar.base.exceptions.ValidateException;
import com.westar.base.model.AffairInfo;
import com.westar.base.model.ImplementDetail;
import com.westar.base.model.UserInfo;
import com.westar.base.pojo.Affair;
import com.westar.base.pojo.WestarResult;
import com.westar.base.util.TokenUtil;
import com.westar.base.util.WestarHttpUtil;
import com.westar.base.validateutil.ValidateEditAffair;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

/**
 * 现场申请的Service
 */
@Service
public class AffairEditScheduledService extends QuartzJobBean {

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private AffairInfoService affairInfoService;

    @Resource
    private AffairEditService affairEditService;

    @Resource
    private AccountLimitService accountLimitService;


    @Resource
    private SystemLogService systemLogService;

    private static Logger logger = LoggerFactory.getLogger( AffairEditScheduledService.class);

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext)
            throws JobExecutionException {
        JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        String type = jobDataMap.getString("type");
        if(type.equals( "handleTask" )){
            AffairInfo affairInfo = (AffairInfo) jobDataMap.get("affairInfo");
            handTask(affairInfo);
        }else if(type.equals( "editTask" )){
            AffairInfo affairInfo = (AffairInfo) jobDataMap.get("affairInfo");
            handleFirst(affairInfo);
        }
    }

    /**
     * 第一次受理
     * @param affairInfo
     */
    public void handleFirst(AffairInfo affairInfo){

        String affairId = affairInfo.getAffairId();
        String account = affairInfo.getOperator();

        //查询密码的次数，判定管是否需要限定时间再次登录
        int errorCount = accountLimitService.countAccountLimit(account);
        if(errorCount > 5 ){
            systemLogService.addSystemLog(account,"-","-1","密码错误超过五次！");
            return;
        }

        //一体化受理编码
        String affairCode = affairInfo.getAffairCode();

        String token = this.getToken( account );
        if(null != token){
            try {
                String actCookie = TokenUtil.getCookie(token, Constant.MODEL_DOTHINGSUI);
                WestarResult westarResult = affairEditService.editAffairEdit(actCookie,affairId,account);
                if(westarResult.getStatus() == 0){
                    //下一步办理人员,默认自己
                    affairInfoService.updateAffairInfo(affairId,"1"  );
                    //添加日志
                    systemLogService.addSystemLog(account,affairInfo.getAffairCode(),"0","受理数据成功！");
                    //发送消息
                    affairInfoService.sendResult(affairCode,0,"受理数据成功！");
                }else{
                    //添加日志
                    systemLogService.addSystemLog(account,affairInfo.getAffairCode(),"-1",westarResult.getData().toString());
                    //发送消息
                    affairInfoService.sendResult(affairCode,-1,westarResult.getData().toString());
                }
                //登录成功，删除所有的密码错误记录
                accountLimitService.deleteAccountLimit(account);
            } catch (SelfHttpException e) {
                if(e.getCode().equals(SelfHttpException.PAGE_RE_LOGIN  ) ){
                    accountLimitService.addAccountLimit(account,errorCount);
                }
                //添加日志
                systemLogService.addSystemLog(account,affairInfo.getAffairCode(),"-1","受理数据，登录异常！");
                //发送消息
                affairInfoService.sendResult(affairCode,-1,"受理数据，登录异常！");
            } catch (Exception e) {
                e.printStackTrace();
                //添加日志
                systemLogService.addSystemLog(account,affairInfo.getAffairCode(),"-1","受理数据，中间件网络异常！");
                //发送消息
                affairInfoService.sendResult(affairCode,-1,"受理数据，中间件网络异常！");
            }


        }
    }


    /**
     * 流程自动办理到办结
     * @param affairInfo
     */
    public void handTask(AffairInfo affairInfo){

        String affairId = affairInfo.getAffairId();

        String affairCode = affairInfo.getAffairCode();
        //获取必要的参数
        Map<String,String> viewTaskParam = this.getInitData(affairInfo);
        //在已办和代办中都没有这个办件
        if(null != viewTaskParam && null != viewTaskParam.get("executor") ){
            //当前办理人
            String account = viewTaskParam.get("executor");
            if(account.equals("-")){
                //添加日志
                systemLogService.addSystemLog(affairInfo.getOperator(),affairCode,"-2","候选人在系统里面密码未设定正确！");
                //发送消息
                affairInfoService.sendResult(affairCode,-2,"候选人在系统里面密码未设定正确！");
                return;
            }

            //查询密码的次数，判定管是否需要限定时间再次登录
            int errorCount = accountLimitService.countAccountLimit(account);
            if(errorCount > 5 ){
                systemLogService.addSystemLog(account,"-","-1","密码错误超过五次！");
                return;
            }
            //登录
            String token = this.getToken( account );
            if(null != token) {
                //认证
                String actCookie = null;
                try {
                    actCookie = TokenUtil.getCookie(token, Constant.MODEL_DOTHINGSUI);

                    //办件受理人员
                    String fisrtHandleAccount = null;
                    //是否从代办查询,默认从代办查询
                    boolean fromTodo = true;
                    if(!account.equals(affairInfo.getOperator())){//办理人不是自己
                        fisrtHandleAccount = affairInfo.getOperator();

                        Map<String,String> viewTaskParamotherPerson = WestarHttpUtil.constrViewTaskParam(actCookie,affairInfo.getAffairCode(),account);
                        if(null == viewTaskParamotherPerson ){
                            //查询taskId
                            String taskId =this.getTaskId(actCookie,affairInfo.getAffairCode());
                            viewTaskParam.put("taskId",taskId);
                            fromTodo =  false;
                        }else{
                            viewTaskParam = viewTaskParamotherPerson;

                        }
                        systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"0","数据由“"+account+"”开始办理！");
                        //发送消息
                        affairInfoService.sendResult(affairCode,0,"数据由“"+account+"”开始办理！");
                    }else{
                        systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"0","数据由受理人员办理！");
                        //发送消息
                        affairInfoService.sendResult(affairCode,0,"数据由受理人员办理！");
                    }
                    //办件
                    WestarResult westarResult = affairEditService.updateHandTask(actCookie,viewTaskParam,fisrtHandleAccount,fromTodo,affairInfo.getAffairCode());

                    //成功办件
                    if(null!= westarResult && westarResult.getStatus() == 0){
                        //办结
                        if(westarResult.getData().equals( "finish" )){
                            affairInfoService.delAffairInfo(affairId);
                            systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"0","正常办结！");
                            //发送消息
                            affairInfoService.sendResult(affairCode,0,"正常办结！");
                        }else{
                            //用办件上传人员来查询下一步骤的办理人员
                            affairInfoService.updateAffairInfo(affairId,"1"  );
                            systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"0","本环节已办理完成！");
                            //发送消息
                            affairInfoService.sendResult(affairCode,0,"本环节已办理完成！");
                        }
                    }else{
                        systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"-1","本环节办理失败！");
                        //发送消息
                        affairInfoService.sendResult(affairCode,-1,"本环节办理失败！");
                    }

                    //登录成功，删除所有的密码错误记录
                    accountLimitService.deleteAccountLimit(account);

                } catch (IOException e) {
                    //发送消息
                    affairInfoService.sendResult(affairCode,-1,"本环节办理网络异常！");
                } catch (SelfHttpException e) {
                    if(e.getCode().equals(SelfHttpException.PAGE_RE_LOGIN  ) ){
                        accountLimitService.addAccountLimit(account,errorCount);
                    }
                    //发送消息
                    affairInfoService.sendResult(affairCode,-1,"本环节账号异常！");
                } catch (Exception e) {
                    //发送消息
                    affairInfoService.sendResult(affairCode,-1,"本环节办理网络异常！");
                }
            }else{
                //发送消息
                affairInfoService.sendResult(affairCode,-1,"本环节办理获取token异常！");
            }
        }else{

            //考虑是否办结，或还在草稿中

            String operator = affairInfo.getOperator();
            //查询密码的次数，判定管是否需要限定时间再次登录
            int errorCount = accountLimitService.countAccountLimit(operator);
            if(errorCount > 5 ){
                systemLogService.addSystemLog(operator,"-","-1","密码错误超过五次！");
                return;
            }

            String token = this.getToken(operator);
            if(null != token) {
                //认证
                String actCookie = null;
                try {
                    actCookie = TokenUtil.getCookie(token, Constant.MODEL_DOTHINGSUI);
                    boolean finishState = ViewTaskUtil.listAffairData(actCookie,affairInfo.getAffairCode());
                    if(finishState){
                        //在办结中
                        affairInfoService.delAffairInfo(affairId);
                        systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"0","正常办结！");
                        affairInfoService.sendResult(affairCode, 0, "正常办结！");
                    }else{

                        //判定是否还在草稿中
                        boolean todoState = ViewTaskUtil.listAffairTodoData(actCookie,affairInfo.getAffairCode());
                        if(todoState){
                            //在草稿中
                            affairInfo.setState("0");
                            handleFirst(affairInfo);
                        }else{
                            systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"-1","办件找不到办理人！");
                            affairInfoService.sendResult(affairCode, -1, "办件找不到办理人！");

                            //登录成功，删除所有的密码错误记录
                            accountLimitService.deleteAccountLimit(operator);
                        }
                    }

                } catch (SelfHttpException e) {
                    if(e.getCode().equals(SelfHttpException.PAGE_RE_LOGIN  ) ){
                        accountLimitService.addAccountLimit(operator,errorCount);
                    }
                    systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"-1","办件查询归档,账号异常！");
                    affairInfoService.sendResult(affairCode, -1, "办件查询归档,账号异常！");
                } catch (Exception e) {
                    systemLogService.addSystemLog(affairInfo.getOperator(),affairInfo.getAffairCode(),"-1","办件查询归档异常！");
                    affairInfoService.sendResult(affairCode, -1, "办件查询归档异常！");
                }
            }else {//发送消息
                affairInfoService.sendResult(affairCode, -1, "本环节办理网络异常！");
            }
        }
    }

    /**
     * 查询待审核的数据
     * @param actCookie
     * @param affairCode
     * @return
     */
    private String getTaskId(String actCookie, String affairCode) {
        String taskId = WestarHttpUtil.constrViewTaskId(actCookie,affairCode);
        return taskId;
    }

    /**
     * 获取执行人以及必要的参数
     * @param affairInfo
     * @return
     */
    private Map<String,String> getInitData(AffairInfo affairInfo) {
        String account = affairInfo.getOperator();
        String token = this.getToken( account );
        if(null != token){
            //一体化受理编号
            String affairCode = affairInfo.getAffairCode();
            try {
                String actCookie = TokenUtil.getCookie(token, Constant.MODEL_DOTHINGSUI);
                //查询创建人的代办
                Map<String,String> viewTaskParam = WestarHttpUtil.constrViewTaskParam(actCookie,affairCode,account);
                //创建人的代办没有，就在已办中查询
                if(null == viewTaskParam){
                    //查询已办
                    viewTaskParam = WestarHttpUtil.constrViewDoneTaskParam(actCookie, affairCode, account);
                    //从已办中找到相应的办理人员
                    WestarResult westarResult = affairEditService.constrViewDoneTaskParam(actCookie, affairCode, account);
                    //找到一个有密码的办理人员
                    if(null!= westarResult && westarResult.getStatus()==0){
                        //查询办件的处理人账号
                        String executor = westarResult.getData().toString();
                        //检查账号的密码()
                        userInfoService.checkExecutor(executor);
                        viewTaskParam.put("executor",executor);
                    }else{
                        //所有候选办理人员都没有密码
                        if(null!= westarResult && westarResult.getStatus()==-1){
                            viewTaskParam.put("executor","-");
                        }else{
                            //已办件中没有找到办理人
                            viewTaskParam.put("executor",null);
                        }
                    }
                }else{
                    //待办里面有这个人
                    viewTaskParam.put("executor",account);
                }
                return viewTaskParam;
            } catch (IOException e) {
                e.printStackTrace();
            } catch (SelfHttpException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    private String getToken(String account) {
        String token = null;
        try {
            token = TokenUtil.getTokenByAccount(account);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SelfHttpException e) {
            e.printStackTrace();
        }

        if(null == token){
            //检查子账号信息
            userInfoService.checkExecutor(account);
            UserInfo userInfo = userInfoService.getUserInfoByAccount(account);
            //检查密码
            String passwd = userInfo.getPasswd();
            if(StringUtils.isEmpty(passwd) || passwd.equals("-")){
                systemLogService.addSystemLog(account,"-","-1","密码已经变动，请及时修改");
                return null;
            }
            try {
                token = TokenUtil.initToken(account,passwd, Constant.MODEL_DOTHINGSUI);
            } catch (IOException e) {
                e.printStackTrace();
            } catch (SelfHttpException e) {
                e.printStackTrace();
            }
            //保存用户
            if(StringUtils.isNotEmpty(token)){
                UserInfo sessionuser = userInfoService.getUserInfoByAccount(account);
                sessionuser.setPasswd(userInfo.getPasswd());
                TokenUtil.updateSessionUser(token,sessionuser);
            }

        }
        return token;
    }
}
